package com.hexinfo.dmpro.common.service;

import cn.hutool.json.JSONObject;
import com.hexinfo.dmpro.common.base.BaseRequest;
import com.hexinfo.dmpro.common.base.BaseService;
import com.hexinfo.dmpro.common.base.Page;
import com.hexinfo.dmpro.common.base.PageResult;
import com.hexinfo.dmpro.common.dao.LogMapper;
import com.hexinfo.dmpro.common.model.Log;
import com.hexinfo.dmpro.common.utils.FileUtil;
import com.hexinfo.dmpro.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;

/**
 * @ClassName LogService
 * @Describe
 * @Author ml.wang
 * @Date 2021-06-16
 */
@Slf4j
@Service
public class LogService extends BaseService {

    @Autowired
    private LogMapper logMapper;

    public List<Log> queryAllInfoLogs(BaseRequest baseRequest) {
        return logMapper.queryInfoLogs(baseRequest);
    }

    public List<Log> queryAllErrorLogs(BaseRequest baseRequest) {
        return logMapper.queryErrorLogs(baseRequest);
    }

    public PageResult queryInfoLogs(BaseRequest baseRequest, Page page) {
        return selectPage(logMapper, "queryInfoLogs", page, baseRequest);
    }

    public PageResult queryErrorLogs(BaseRequest baseRequest, Page page) {
        return selectPage(logMapper, "queryErrorLogs", page, baseRequest);
    }

    public PageResult queryLogsByUsername(BaseRequest baseRequest, Page page) {
        return selectPage(logMapper, "queryAll", page, baseRequest);
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(String username, String browser, String ip, ProceedingJoinPoint joinPoint, Log logObj) {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        com.hexinfo.dmpro.common.annotation.Log logAop =
                method.getAnnotation(com.hexinfo.dmpro.common.annotation.Log.class);

        // 方法路径
        String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";

        StringBuilder params = new StringBuilder("{");
        //参数值
        Object[] argValues = joinPoint.getArgs();
        //参数名称
        String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        if (argValues != null) {
            for (int i = 0; i < argValues.length; i++) {
                params.append(" ").append(argNames[i]).append(": ").append(argValues[i]);
            }
        }
        params.append("}");

        // 描述
        if (logObj != null) {
            logObj.setDescription(logAop.value());
        }
        assert logObj != null;
        logObj.setRequestIp(ip);

        String loginPath = "login";
        if (loginPath.equals(signature.getName())) {
            try {
                assert argValues != null;
                username = new JSONObject(argValues[0]).get("username").toString();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        logObj.setAddress(StringUtils.getCityInfo(logObj.getRequestIp()));
        logObj.setMethod(methodName);
        logObj.setUsername(username);
        logObj.setParams(params.toString());
        logObj.setBrowser(browser);
        logObj.setCreateTime(new Timestamp(System.currentTimeMillis()));
        logMapper.save(logObj);
    }

    public void delAllInfoLogs() {
        logMapper.delAllInfoLogs();
    }

    public void delAllErrorLogs() {
        logMapper.delAllErrorLogs();
    }

    public void download(List<Log> logs, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Log log : logs) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("用户名", log.getUsername());
            map.put("IP", log.getRequestIp());
            map.put("IP来源", log.getAddress());
            map.put("描述", log.getDescription());
            map.put("浏览器", log.getBrowser());
            map.put("请求耗时/毫秒", log.getTime());
            map.put("异常详情", log.getExceptionDetail() != null ? log.getExceptionDetail() : "");
            map.put("创建日期", log.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

}
